package com.nd.fastdp.admin.controller.objcode;

import cn.hutool.core.util.ZipUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nd.fastdp.framework.annotation.CurrentUser;
import com.nd.fastdp.framework.pojo.bo.LoginUser;
import com.nd.fastdp.framework.pojo.constant.YestNoEnum;
import com.nd.fastdp.framework.pojo.dto.DelParam;
import com.nd.fastdp.framework.pojo.vo.Result;
import com.nd.fastdp.framework.properties.FdpProperties;
import com.nd.fastdp.objcode.config.ObjCodeConfig;
import com.nd.fastdp.objcode.model.bo.ObjCodeBO;
import com.nd.fastdp.objcode.model.bo.ObjCodeDetailBO;
import com.nd.fastdp.objcode.model.dto.ObjCodeAddParam;
import com.nd.fastdp.objcode.model.dto.ObjCodeDetailListParam;
import com.nd.fastdp.objcode.model.dto.ObjCodeListParam;
import com.nd.fastdp.objcode.model.dto.ObjCodeQueryParam;
import com.nd.fastdp.objcode.service.ObjCodeService;
import com.nd.fastdp.objcode.util.CryptoUtil;
import com.nd.fastdp.objcode.util.RqCodeUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@RestController
@RequestMapping("/base/objcode")
@Api(tags={"一物一码"})
public class ObjCodeController {

    @Autowired
    private ObjCodeService objCodeService;

    @Autowired
    private FdpProperties fdpProperties;

    @Autowired
    private ObjCodeConfig objCodeConfig;

    @PostMapping("/add")
    @ApiOperation(value = "创建")
    public Result add(@ApiIgnore @CurrentUser LoginUser loginUser, @RequestBody ObjCodeAddParam param) {

        param.setLoginUser(loginUser);

        objCodeService.add(param);

        return Result.OK();
    }

    @PostMapping("/del")
    @ApiOperation(value = "删除")
    public Result del(@ApiIgnore @CurrentUser LoginUser loginUser, @RequestBody(required = true) List<String> ids) {

        DelParam param = new DelParam();

        param.setIds(ids);
        param.setLoginUser(loginUser);

        objCodeService.del(param);

        return Result.OK();
    }

    @GetMapping("/get/{id}")
    @ApiOperation(value = "详情")
    public Result get(@PathVariable("id") String id){

        ObjCodeBO objCode = objCodeService.get(id);

        return Result.OK(objCode);
    }

    @PostMapping("/listDetail")
    @ApiOperation(value = "详情列表")
    public Result listDetail(@RequestBody(required = false) ObjCodeDetailListParam param){

        List<ObjCodeDetailBO> list = objCodeService.list(param);

        return Result.OK(list);
    }

    @PostMapping("/list")
    @ApiOperation(value = "列表")
    public Result list(@ApiIgnore @CurrentUser LoginUser loginUser, @RequestBody(required = false) ObjCodeListParam param){

        param.setLoginUser(loginUser);

        List<ObjCodeBO> list = objCodeService.list(param);

        return Result.OK(list);
    }

    @PostMapping("/page")
    @ApiOperation(value = "分页查询")
    public Result page(@ApiIgnore @CurrentUser LoginUser loginUser, @RequestBody(required = false) ObjCodeQueryParam param) {

        param.setLoginUser(loginUser);

        Page<ObjCodeBO> page =  objCodeService.page(param);

        return Result.OK(page);
    }

    @PostMapping("/count")
    @ApiOperation(value = "生码次数")
    public Result count(@ApiIgnore @CurrentUser LoginUser loginUser, @RequestBody(required = false) ObjCodeListParam param){

        param.setLoginUser(loginUser);

        Integer count = objCodeService.count(param);

        return Result.OK(count);
    }

    @PostMapping("/codeCount")
    @ApiOperation(value = "物码总数")
    public Result codeCount(@ApiIgnore @CurrentUser LoginUser loginUser, @RequestBody(required = false) ObjCodeListParam param){

        param.setLoginUser(loginUser);

        Integer count = objCodeService.codeCount(param);

        return Result.OK(count);
    }

    @PostMapping("/codeUsedCount")
    @ApiOperation(value = "已使用数量")
    public Result codeUsedCount(@ApiIgnore @CurrentUser LoginUser loginUser, @RequestBody(required = false) ObjCodeListParam param){

        param.setLoginUser(loginUser);

        Integer count = objCodeService.codeUsedCount(param);

        return Result.OK(count);
    }

    @PostMapping("/detailCount")
    @ApiOperation(value = "明细物码数量")
    public Result detailCount(@ApiIgnore @CurrentUser LoginUser loginUser, @RequestBody(required = false) ObjCodeDetailListParam param){

        param.setLoginUser(loginUser);

        Integer count = objCodeService.count(param);

        return Result.OK(count);
    }

    private String getCodePath(String codeId, String salt){

        Long timeStamp = System.currentTimeMillis();
        String path = fdpProperties.getDomainName() + objCodeConfig.getDefaultPath() + "?codeId=" + codeId + "&timeStamp=" + timeStamp + "&ciphertext=" + CryptoUtil.encrypt(codeId, timeStamp, salt);

        return path;
    }

    @GetMapping("/dowmload/{id}")
    @ApiOperation(value = "导出")
    public void print(@PathVariable("id") String id, HttpServletRequest request, HttpServletResponse response) throws IOException {

        ObjCodeBO objCode = objCodeService.get(id);
        List<ObjCodeDetailBO> list = objCodeService.findById(id);

        List<File> files = new ArrayList<File>();

        String content = objCodeConfig.getDefaultPath();
        for (ObjCodeDetailBO detail : list){

            if(objCode.getHasDesc().intValue() == YestNoEnum.YES.getValue().intValue()){
                files.add(RqCodeUtil.hasDescRqCode(detail.getName(), detail.getNo(), getCodePath(detail.getId(), objCode.getSalt()), objCode.getDescBackColor()));
            }else{
                files.add(RqCodeUtil.simpleRqCode(detail.getName() + "_" + detail.getNo(), getCodePath(detail.getId(), objCode.getSalt())));
            }
        }

        File zipFile = File.createTempFile(objCode.getId() + "_" + System.currentTimeMillis(), "zip");
        zipFile.deleteOnExit();

        ZipUtil.zip(zipFile, false, files.toArray(new File[]{}));

        if (zipFile != null && zipFile.exists()) {
            response.setContentType("application/octet-stream");
            response.setHeader("content-type", "application/octet-stream");
            response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(objCode.getName() + ".zip", "UTF-8"));
            byte[] buffer = new byte[1024];
            FileInputStream fis = null;
            BufferedInputStream bis = null;
            try {
                fis = new FileInputStream(zipFile);
                bis = new BufferedInputStream(fis);
                OutputStream os = response.getOutputStream();
                int i = bis.read(buffer);
                while (i != -1) {
                    os.write(buffer, 0, i);
                    i = bis.read(buffer);
                }

                new Thread(new Runnable() {
                    @Override
                    public void run() {

                        for (File file : files){
                            if(file.exists()){
                                file.delete();
                            }
                        }

                        if(zipFile.exists()){
                            zipFile.delete();
                        }

                    }
                }).start();

            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (bis != null)  bis.close();
                if (fis != null) fis.close();
            }
        }else{
            response.setContentType("text/html;charset=UTF-8");
            response.setCharacterEncoding("UTF-8");

            response.getWriter().write("导出失败");
        }
    }

    @GetMapping("/singleDowmload/{id}")
    @ApiOperation(value = "单一导出")
    public void singleDowmload(@PathVariable("id") String id, HttpServletRequest request, HttpServletResponse response) throws IOException {


        ObjCodeDetailBO detailBO = objCodeService.getDetail(id);
        ObjCodeBO objCodeBO = objCodeService.get(detailBO.getObjCodeId());

        String content = objCodeConfig.getDefaultPath();
        File file = null;

        if(objCodeBO.getHasDesc().intValue() == YestNoEnum.YES.getValue()){
            file = RqCodeUtil.hasDescRqCode(detailBO.getName(), detailBO.getNo(), getCodePath(detailBO.getId(), objCodeBO.getSalt()), objCodeBO.getDescBackColor());
        }else{
            file = RqCodeUtil.simpleRqCode(detailBO.getName() + "_" + detailBO.getNo(), getCodePath(detailBO.getId(), objCodeBO.getSalt()));

        }

        if (file != null && file.exists()) {
            response.setContentType("application/octet-stream");
            response.setHeader("content-type", "application/octet-stream");
            response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(file.getName(), "UTF-8"));
            byte[] buffer = new byte[1024];
            FileInputStream fis = null;
            BufferedInputStream bis = null;
            try {
                fis = new FileInputStream(file);
                bis = new BufferedInputStream(fis);
                OutputStream os = response.getOutputStream();
                int i = bis.read(buffer);
                while (i != -1) {
                    os.write(buffer, 0, i);
                    i = bis.read(buffer);
                }

            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (bis != null)  bis.close();
                if (fis != null) fis.close();
            }
        }else{
            response.setContentType("text/html;charset=UTF-8");
            response.setCharacterEncoding("UTF-8");

            response.getWriter().write("导出失败");
        }

    }

    @GetMapping("/preView")
    @ApiOperation(value = "预览")
    public void preView(@RequestParam String params, HttpServletRequest request, HttpServletResponse response) throws IOException {

        ObjCodeBO objCodeBO = JSON.parseObject(params, ObjCodeBO.class);

        if(StringUtils.isNotEmpty(objCodeBO.getDescBackColor())){
            objCodeBO.setDescBackColor("#" + objCodeBO.getDescBackColor());
        }else{
            objCodeBO.setDescBackColor(objCodeConfig.getDefaultBackColor());
        }

        ObjCodeDetailBO detailBO = new ObjCodeDetailBO();
        detailBO.setId(UUID.randomUUID().toString());
        detailBO.setNo(objCodeBO.getPrefix() + objCodeBO.getStartVal());
        detailBO.setName(objCodeBO.getName());

        File file = null;

        if(objCodeBO.getHasDesc().intValue() == YestNoEnum.YES.getValue().intValue()){
            file = RqCodeUtil.hasDescRqCode(detailBO.getName(), detailBO.getNo(), "技术支持: 15191969253", objCodeBO.getDescBackColor());
        }else{
            file = RqCodeUtil.simpleRqCode("技术支持: 15191969253");
        }

        if (file != null && file.exists()) {
            response.setContentType("application/octet-stream");
            response.setHeader("content-type", "application/octet-stream");
            response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(file.getName(), "UTF-8"));
            byte[] buffer = new byte[1024];
            FileInputStream fis = null;
            BufferedInputStream bis = null;
            try {
                fis = new FileInputStream(file);
                bis = new BufferedInputStream(fis);
                OutputStream os = response.getOutputStream();
                int i = bis.read(buffer);
                while (i != -1) {
                    os.write(buffer, 0, i);
                    i = bis.read(buffer);
                }

            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (bis != null)  bis.close();
                if (fis != null) fis.close();
            }
        }else{
            response.setContentType("text/html;charset=UTF-8");
            response.setCharacterEncoding("UTF-8");

            response.getWriter().write("导出失败");
        }

    }

}
